/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.serviceapp.service.organization.impl;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qinyeit.serviceapp.entity.*;
import com.qinyeit.serviceapp.entity.enums.*;
import com.qinyeit.serviceapp.entity.system.ManagementAccount;
import com.qinyeit.serviceapp.entity.system.ManagementPermission;
import com.qinyeit.serviceapp.entity.system.ManagementRole;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.redis.RedisKeyHelper;
import com.qinyeit.serviceapp.repository.organization.PrintSettingOrderRepository;
import com.qinyeit.serviceapp.service.auxiliary.CommentService;
import com.qinyeit.serviceapp.service.branchstores.BranchSupplierService;
import com.qinyeit.serviceapp.service.branchstores.BranchWarehouseService;
import com.qinyeit.serviceapp.service.materials.MaterialUnitService;
import com.qinyeit.serviceapp.service.organization.DistrictService;
import com.qinyeit.serviceapp.service.organization.EmployeeService;
import com.qinyeit.serviceapp.service.organization.PrivilegeTemplateService;
import com.qinyeit.serviceapp.service.pays.PaymentService;
import com.qinyeit.serviceapp.service.stores.SupplierService;
import com.qinyeit.serviceapp.service.stores.WarehouseService;
import com.qinyeit.serviceapp.service.system.ManagementAccountService;
import com.qinyeit.serviceapp.service.system.ManagementPermissionService;
import com.qinyeit.serviceapp.service.system.ManagementRoleService;
import com.qinyeit.serviceapp.service.system.impl.SmsServiceImpl;
import com.qinyeit.serviceapp.utils.Lang;
import com.qinyeit.serviceapp.utils.LocalUtils;
import com.qinyeit.serviceapp.utils.SearchUtils;
import com.qinyetech.springstage.core.date.DateUtils;
import com.qinyetech.springstage.core.entity.search.SearchOperator;
import com.qinyetech.springstage.core.entity.search.Searchable;
import com.qinyetech.springstage.core.lang.QyMap;
import com.qinyetech.springstage.core.repository.jdbc.PageNamedParameterJdbcTemplate;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.qinyetech.springstage.core.service.BaseService;
import com.qinyeit.serviceapp.repository.organization.MerchantGroupRepository;
import com.qinyeit.serviceapp.service.organization.MerchantGroupService;

import java.util.*;
import java.util.concurrent.TimeUnit;

import static javafx.scene.input.KeyCode.R;

/** 
 * ClassName: MerchantGroupServiceImpl <br/> 
 * Function: 连锁店 业务实现 <br/> 
 * date: 2018-11-20 11:05:18 <br/> 
 * 
 * @author liuwenjin
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@Transactional
public class MerchantGroupServiceImpl extends BaseService<MerchantGroup, Long> implements MerchantGroupService {


	@Autowired
	private MerchantGroupRepository merchantGroupRepository;
	@Autowired
	private StringRedisTemplate stringRedisTemplate;
	@Autowired
	private SmsServiceImpl smsService;
	@Autowired
	private ManagementAccountService managementAccountService;
	@Autowired
	private EmployeeService employeeService;
	@Autowired
	private DistrictService districtService;
	@Autowired
	private ManagementRoleService managementRoleService;
	@Autowired
	private PrivilegeTemplateService privilegeTemplateService;
	@Autowired
	private BranchSupplierService branchSupplierService;
	@Autowired
	private BranchWarehouseService branchWarehouseService;
	@Autowired
	private PaymentService paymentService;
	@Autowired
	private ManagementPermissionService managementPermissionService;
	@Autowired
	private CommentService commentService;
	@Autowired
	private MaterialUnitService materialUnitService;
	@Autowired
	private WarehouseService warehouseService;
	@Autowired
	private SupplierService supplierService;
	@Autowired
	private PrintSettingOrderRepository printSettingOrderRepository;
	@Autowired
	private PageNamedParameterJdbcTemplate jdbcTemplate;



	@Override
	public MerchantGroup registerMerchantGroups(JSONObject json) {

		if(json==null){
			throw new BusinessRunTimeException("请填写注册信息，信息不能为空",10001);
		}

		JSONObject accountData = json.getJSONObject("formLabelAlign"); //账号信息
		JSONObject merchantGroupData = json.getJSONObject("merchantGroup"); //商户信息
		//公司名
		String companyName = merchantGroupData.getString("companyName");
		String address = merchantGroupData.getString("address");
		String linker = merchantGroupData.getString("linker");
		String telephone = merchantGroupData.getString("telephone");
		verify(json);

		String name = accountData.getString("name");
		String phone = accountData.getString("phone");
		String realName = accountData.getString("realName");
		String code = accountData.getString("code");
		String password = accountData.getString("password");
		String passwordConfirm = accountData.getString("passwordConfirm");

		MerchantGroup merchantGroup = new MerchantGroup();
		merchantGroup.setAddress(address);
		merchantGroup.setLinker(linker);
		merchantGroup.setPhone(phone);
		merchantGroup.setTelephone(telephone);
		merchantGroup.setCompanyName(companyName);
		merchantGroup = this.save(merchantGroup);

		//保存账号信息
		ManagementAccount account = new ManagementAccount();
		account.setAccount(name);
		account.setRealName((StringUtils.isBlank(name))?"管理员":realName);
		account.setPassword(password);
		account.setAdmin(true);
		account.setMerchantGroupId(merchantGroup.getId());
		account.setPasswordConfirm(passwordConfirm);
		account.setLocked(false);
		account = managementAccountService.save(account);

		merchantGroup.setAccount(account);
		merchantGroup = this.update(merchantGroup);

		if(merchantGroup!=null){
			this.initData(merchantGroup, account);
		}

		return merchantGroup;
	}

	@Override
	public void verify(JSONObject data) {

		if(data==null){
			throw new BusinessRunTimeException("请填写注册信息，信息不能为空",10001);
		}
		JSONObject accountData = data.getJSONObject("formLabelAlign"); //账号信息
		//获取激活码
		String activityKey = accountData.getString("activeKey");
		if(StringUtils.isBlank(activityKey)){
			throw new BusinessRunTimeException("请输入激活码",10002);
		}

		String password = accountData.getString("password");
		String passwordConfirm = accountData.getString("passwordConfirm");

		if(password==null || passwordConfirm==null){
			throw new BusinessRunTimeException("密码或确认密码不能为空",1004);
		}
		if(!password.equals(passwordConfirm)){
			throw new BusinessRunTimeException("两次密码输入不一致",1002);
		}

		String name = accountData.getString("name");
		String phone = accountData.getString("phone");
		String realName = accountData.getString("realName");
		String code = accountData.getString("code");

		if(StringUtils.isBlank(phone)){
			throw new BusinessRunTimeException("手机号不能为空",1001);
		}

		//手机短信验证码
		if(StringUtils.isBlank(code)){
			throw new BusinessRunTimeException("验证码不能为空",1001);
		}
		//验证[短信验证码]是否正确
		verifyCode(phone,code);

		Searchable searchable;
		searchable=Searchable.newSearchable();
		searchable.addSearchFilter("phone", SearchOperator.eq,phone);
		MerchantGroup merchantGroup=this.findOne(searchable);
		if(merchantGroup!=null){
			throw new BusinessRunTimeException("该手机号已经被绑定",1001);
		}

		//账号已存在
		searchable = Searchable.newSearchable();
		searchable.addSearchParam("account_eq",name);
		searchable.addSearchParam("admin_eq",true);
		ManagementAccount account = managementAccountService.findOne(searchable);
		if (account!=null){
			throw new BusinessRunTimeException("账号已存在",10002);
		}
	}

	@Override
	public void sendCode(String phone) {
		if (phone == null || "".equals(phone.trim())) {
			throw new BusinessRunTimeException("手机号不能为空", 10001);
		}

		if (!Lang.isMobile(phone)) {
			throw new BusinessRunTimeException("手机号不正确", 10003);
		}

		if (StringUtils.isBlank(phone)){
			throw new BusinessRunTimeException("手机号为空",20001);
		}
		//rediskey
		String redisKey= RedisKeyHelper.genSmsKey(phone);
		if(isContinuousSend(redisKey)){
			throw new BusinessRunTimeException("1分钟之内不能连续发送",50002);
		}
		//随机生成短信验证码
		String smsCode = RandomStringUtils.randomNumeric(4);
		log.info("-------------短信验证码：{}",smsCode);

		//log.info("短信验证码："+smsCode);
		/*smsService.sendSingleMsg(
				smsService.getRegisteredTemplateId(),
				phone,
				QyMap.NEW().setv("code",smsCode));
*/
		BoundHashOperations<String,String,String> hashOperations= stringRedisTemplate.boundHashOps(redisKey);
		Map<String,String> hash= Maps.newHashMap();
		hash.put("code",smsCode);
		hash.put("time",System.currentTimeMillis()+"");
		hashOperations.putAll(hash);
		stringRedisTemplate.expire(redisKey,3, TimeUnit.MINUTES);//有效期10分钟
	}


	@Override
	public void verifyCode(String tel, String inputCode) {
		inputCode = inputCode.trim();

		//特殊情况下, 使用万能短信验证码快速通过
		String allPowerfulCode = DateUtils.format(new Date(), "yyMMddHH");
		if(allPowerfulCode.equalsIgnoreCase(inputCode)){
			return;
		}

		//获取redis的短信验证码 与 本次填写的验证码比较
		String redisKey = RedisKeyHelper.genSmsKey(tel);
		if(!stringRedisTemplate.hasKey(redisKey)){
			throw new BusinessRunTimeException("短信验证码不正确",100003);
		}
		BoundHashOperations<String,String,String> hashOperations= stringRedisTemplate.boundHashOps(redisKey);
		String correctCode = hashOperations.get("code");
		if (StringUtils.equals(correctCode,inputCode)){
			return;
		}else {
			throw new BusinessRunTimeException("短信验证码不正确",100004);
		}
	}

	@Override
	public void initData(MerchantGroup merchantGroup, ManagementAccount account) {
		//区域根节点
		District district = new District();
		district.setName(merchantGroup.getCompanyName());
		district.setParentId(0L);
		district.setParentIds("0/");
		district.setMerchantGroupId(merchantGroup.getId());
		district.setHasChildren(false);
		district.setWeight(0);
		district = districtService.save(district);

		//角色
		ManagementRole role = new ManagementRole();
		//将所有权限给超级管理员
		Searchable searchable = SearchUtils.newSearchableWidthDeletedFilter();
		List<ManagementPermission> permissionList = managementPermissionService.findWithSort(searchable);
		Set<ManagementPermission> permissionSet = new HashSet<>();
		if (CollectionUtils.isNotEmpty(permissionList)){
			for (ManagementPermission permission : permissionList) {
				permissionSet.add(permission);
			}
			role.setPermissions(permissionSet);
		}
		role.setName("超级管理员"); //普通客户， 测试用，没有任何权限
		role.setCode(ManagementRole.ADMINISTRATOR_CODE);
		role.setDeleteAble(false);
		role.setMerchantGroupId(merchantGroup.getId());
//		role.setAttachDistrictId(district.getId());
		role = managementRoleService.save(role);

		Set<ManagementRole> roles = new HashSet<>();
		roles.add(role);
		account.setRoles(roles);
		managementAccountService.update(account);





		//员工表（employees）中初始化管理员员工 将管理员员工关联到管理员账号上
		Employee employee = new Employee();
		employee.setMerchantGroupId(merchantGroup.getId());
		employee.setAccount(account);
		employee.setName(account.getRealName());
		employee.setAvatar(account.getHeadPic());
		employee.setDistrictId(district.getId());
		employee.setAttachDataPermission("*");
		employee = employeeService.save(employee);

		role = new ManagementRole();
		role.setName("直营店模板（系统默认）");
		role.setType(RoleType.BRANCHROLE);
		role.setMerchantGroupId(merchantGroup.getId());
		role.setCode("merchant_"+LocalUtils.getUUID());
		role.setState(State.NORMAL);
		role.setDescription("直营店模板（系统默认）");
		role.setDeleteAble(false);
		role.setOperatorName(employee.getName());
		managementRoleService.save(role);

		role = new ManagementRole();
		role.setName("加盟店模板（系统默认）");
		role.setType(RoleType.BRANCHROLE);
		role.setMerchantGroupId(merchantGroup.getId());
		role.setCode("merchant_"+LocalUtils.getUUID());
		role.setState(State.NORMAL);
		role.setDescription("加盟店模板（系统默认）");
		role.setDeleteAble(false);
		role.setOperatorName(employee.getName());
		managementRoleService.save(role);

//		//默认权限模板
//		PrivilegeTemplate template = new PrivilegeTemplate();
//		template.setName("直营店模板（系统默认）");
//		template.setOperatorName(employee.getOperatorName());
//		template.setOperator(employee.getId());
//		template.setDef(true);
//		template.setMerchantGroupId(merchantGroup.getId());
//		privilegeTemplateService.save(template);
//
//		template = new PrivilegeTemplate();
//		template.setName("加盟店模板（系统默认）");
//		template.setOperatorName(employee.getOperatorName());
//		template.setOperator(employee.getId());
//		template.setDef(true);
//		template.setMerchantGroupId(merchantGroup.getId());
//		privilegeTemplateService.save(template);


		//总部仓库默认数据
		Warehouse warehouse = new Warehouse();
		warehouse.setName("默认仓库");
		warehouse.setSys(true);
		warehouse.setNo("ZC001");
		warehouse.setState(State.NORMAL);
		warehouse.setMerchantGroupId(merchantGroup.getId());
		warehouseService.save(warehouse);

		//总部供应商默认数据
		Supplier supplier = new Supplier();
		supplier.setMerchantGroupId(merchantGroup.getId());
		supplier.setName("默认供应商");
		supplier.setNo("1001");
		supplier.setState(State.NORMAL);
		supplierService.save(supplier);


		//门店默认供应商
		BranchSupplier branchSupplier = new BranchSupplier();
		branchSupplier.setNo("ZB001");
		branchSupplier.setName("总部配送中心");
		branchSupplier.setOperateTime(DateUtils.date());
		branchSupplier.setOperatorName(employee.getName());
		branchSupplier.setLinker(merchantGroup.getLinker());
		branchSupplier.setMerchantGroupId(merchantGroup.getId());
		branchSupplier.setPhone(merchantGroup.getPhone());
		branchSupplier.setUuid(LocalUtils.getUUID());
		branchSupplier.setUpdateTimestamp(DateUtils.current());
		branchSupplierService.save(branchSupplier);

		//门店默认仓库
		BranchWarehouse branchWarehouse = new BranchWarehouse();
		branchWarehouse.setMerchantGroupId(merchantGroup.getId());
		branchWarehouse.setOperatorName(employee.getName());
		branchWarehouse.setOperateTime(DateUtils.date());
		branchWarehouse.setName("门店仓库");
		branchWarehouse.setNo("CK001");
		branchWarehouse.setSys(true);
		branchWarehouse.setUuid(LocalUtils.getUUID());
		branchWarehouse.setUpdateTimestamp(DateUtils.current());
		branchWarehouseService.save(branchWarehouse);

		searchable = Searchable.newSearchable();
		searchable.addSearchFilter("merchantGroupId", SearchOperator.eq, merchantGroup.getId());

		//付款方式默认三个
		Payment payment = new Payment();
		payment.setOperateTime(DateUtils.date());
		payment.setOperatorName(employee.getName());
		payment.setMerchantGroupId(merchantGroup.getId());
		payment.setName("现金支付");
		payment.setType(PaymentType.CASH);
		payment.setUuid(LocalUtils.getUUID());
		payment.setUpdateTimestamp(DateUtils.current());
		payment.setRemark("默认支付方式，不可删除");
		payment.setDeleteAble(false);
		paymentService.save(payment);
		//付款方式默认三个
		payment = new Payment();
		payment.setOperateTime(DateUtils.date());
		payment.setOperatorName(employee.getName());
		payment.setMerchantGroupId(merchantGroup.getId());
		payment.setName("会员卡支付");
		payment.setType(PaymentType.VIPCARD);
		payment.setUuid(LocalUtils.getUUID());
		payment.setUpdateTimestamp(DateUtils.current());
		payment.setRemark("默认支付方式，不可删除");
		payment.setDeleteAble(false);
		paymentService.save(payment);
		//付款方式默认三个
		payment = new Payment();
		payment.setOperateTime(DateUtils.date());
		payment.setOperatorName(employee.getName());
		payment.setMerchantGroupId(merchantGroup.getId());
		payment.setName("挂账支付");
		payment.setType(PaymentType.GUAZHANG);
		payment.setUuid(LocalUtils.getUUID());
		payment.setUpdateTimestamp(DateUtils.current());
		payment.setRemark("默认支付方式，不可删除");
		payment.setDeleteAble(false);
		paymentService.save(payment);
		//付款方式默认三个
		payment = new Payment();
		payment.setOperateTime(DateUtils.date());
		payment.setOperatorName(employee.getName());
		payment.setMerchantGroupId(merchantGroup.getId());
		payment.setName("悦收银");
		payment.setType(PaymentType.CASHIER);
		payment.setUuid(LocalUtils.getUUID());
		payment.setUpdateTimestamp(DateUtils.current());
		payment.setRemark("默认支付方式，不可删除");
		payment.setDeleteAble(false);
		paymentService.save(payment);

		//新增辅助信息
		/*
		* 反结原因：a. 收银员结算错误, b. 商品漏算，c. 结算时客户未出示会员卡
		  退菜原因：a. 服务员点错了，b.顾客不想要了, c. 商品质量出问题
		  免单原因：a. 老客户介绍新客户, b.老板朋友， c. 活动免单
		  赠菜原因：a. 老客户介绍新客户, b.老板朋友， c. 活动免单, d. 客户提出了有建设性的建议
		  折扣原因：a. 老客户介绍新客户, b.老板朋友， c. 活动免单
		  口味原因：a. 不要辣, b.少点辣, c.多点辣, d.不要蒜 e.不要香菜 g.不要葱
		  外卖取要原因：a.客户不想要了
		* */
		Comment comment = new Comment();
		comment.setType(CommentType.FANJIE);
		comment.setName("收银员结算错误");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.FANJIE);
		comment.setName("商品漏算");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.FANJIE);
		comment.setName("结算时客户未出示会员卡");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);

		comment = new Comment();
		comment.setType(CommentType.TUICAI);
		comment.setName("服务员点错了");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.TUICAI);
		comment.setName("顾客不想要了");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.TUICAI);
		comment.setName("商品质量出问题");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);

		comment = new Comment();
		comment.setType(CommentType.MIANDAN);
		comment.setName("老客户介绍新客户");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.MIANDAN);
		comment.setName("老板朋友");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.MIANDAN);
		comment.setName("活动免单");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);

		comment = new Comment();
		comment.setType(CommentType.ZENGCAI);
		comment.setName("老客户介绍新客户");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.ZENGCAI);
		comment.setName("老板朋友");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.ZENGCAI);
		comment.setName("活动免单");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.ZENGCAI);
		comment.setName("客户提出了有建设性的建议");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);

		comment = new Comment();
		comment.setType(CommentType.ZHEKOU);
		comment.setName("老客户介绍新客户");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.ZHEKOU);
		comment.setName("老板朋友");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.ZHEKOU);
		comment.setName("活动免单");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);

		comment = new Comment();
		comment.setType(CommentType.KOUWEI);
		comment.setName("不要辣");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.KOUWEI);
		comment.setName("少点辣");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.KOUWEI);
		comment.setName("多点辣");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.KOUWEI);
		comment.setName("不要蒜");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.KOUWEI);
		comment.setName("不要香菜");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);
		comment = new Comment();
		comment.setType(CommentType.KOUWEI);
		comment.setName("不要葱");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);

		comment = new Comment();
		comment.setType(CommentType.WAIMAIQUXIAO);
		comment.setName("客户不想要了");
		comment.setUpdateTimestamp(DateUtils.current());
		comment.setOperateTime(DateUtils.date());
		comment.setUuid(LocalUtils.getUUID());
		comment.setOperatorName(employee.getName());
		comment.setSys(true);
		comment.setMerchantGroupId(merchantGroup.getId());
		commentService.save(comment);


		//原料单位
		Long count = materialUnitService.count(searchable);
		if(count.intValue()==0){
			//单位初始化
			String [] units = {
					"斤","袋","克","箱","板","盒","串","瓶","毫升","升","双","件","条","个","张",
					"桶","根","包","捆","听","付","卷","支","把","台","米","平米","本","块","千克",
					"提","对","床","片","份",
			};
			MaterialUnit unit;
			int index = 1;
			for (String name : units) {
				unit = new MaterialUnit();
				unit.setName(name);
				unit.setNo(StringUtils.leftPad(index+"", 3, "0"));
				unit.setState(State.NORMAL);
				unit.setMerchantGroupId(merchantGroup.getId());
				unit.setUpdateTimestamp(DateUtils.current());
				unit.setUuid(LocalUtils.getUUID());
				materialUnitService.save(unit);
				index++;
			}
		}


		//单据打印配置初始化
		orderPrintSetFormat(merchantGroup.getId());


	}


	/**
	 * 初始化单据打印参数项
	 * @param merchantGroupId 商户组ID
	 * @author liuwenjin
	 * @date 2019-03-04
	 * @return true-成功, false-失败
	 */
	@Override
	public boolean orderPrintSetFormat(Long merchantGroupId){
		if(merchantGroupId==null){
			return false;
		}
		String[] orderTitles = {
				"总部订单",
				"总部入库单",
				"总部出库单",
				"总部调拨单"
		};
		PrintSettingOrderType[] printSettingOrderTypes = {
				PrintSettingOrderType.PURCHASEORDER,
				PrintSettingOrderType.STOREIN,
				PrintSettingOrderType.STOREOUT,
				PrintSettingOrderType.TRANSFERORDER
		};

		//key-单据枚举自变量, value-单据列
		Map<String, Object> orderColumnMap = new HashMap<>();
		Map<String, Object> tableColumnMap = new HashMap<>();
		List<QyMap> list = null;
		QyMap map = null;

		//[单据打印设置 - 总部入库单]
		list = new ArrayList<>();
		map = QyMap.map("name", "商户")
				.setv("code","merchantId")
				.setv("data_controle",0); //0-系统默认不允许调整/1-客户自定义显示列
		list.add(map);

		map = QyMap.map("name","主键")
				.setv("code","id")
				.setv("data_controle",0);
		list.add(map);

		map = QyMap.map("name","编号")
				.setv("code","no")
				.setv("data_controle",1);
		list.add(map);

		map =QyMap.map("name", "仓库")
				.setv("code","warehouse")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "供应商")
				.setv("code", "supplier")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "操作人");
		map.setv("code", "founder")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "商品信息库")
		.setv("code", "store_name")
				.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "订单日期")
		.setv("code", "purchase_time")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "收货日期")
		.setv("code", "accept_time")
		.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "收货地址")
		.setv("code", "address")
		.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "备注")
		.setv("code", "remark")
		.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "订单金额")
		.setv("code", "amount")
		.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "订单状态")
		.setv("code", "state")
		.setv("data_controle",1);
		list.add(map);
		orderColumnMap.put(PrintSettingOrderType.PURCHASEORDER.getKey(), list);

		//[单据打印设置 -总部入库设置]
		list = Lists.newArrayList();
		map = QyMap.map("name", "商户")
				.setv("code","merchantId")
				.setv("data_controle",0); //0-系统默认不允许调整/1-客户自定义显示列
		list.add(map);

		map = QyMap.map("name","主键")
				.setv("code","id")
				.setv("data_controle",0);
		list.add(map);

		map = QyMap.map("name","编号")
				.setv("code","no")
				.setv("data_controle",1);
		list.add(map);

		map =QyMap.map("name", "仓库")
				.setv("code","warehouse")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "供应商")
				.setv("code", "supplier")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "操作人");
		map.setv("code", "founder")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "商品信息库")
				.setv("code", "store_name")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "单据类型")
				.setv("code", "type")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "订单日期")
				.setv("code", "purchase_time")
				.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "备注")
				.setv("code", "remark")
				.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "订单金额")
				.setv("code", "amount")
				.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "订单状态")
				.setv("code", "state")
				.setv("data_controle",1);
		list.add(map);
		orderColumnMap.put(PrintSettingOrderType.STOREIN.getKey(), list);


		//[单据打印设置 - 总部出库]
		list = Lists.newArrayList();
		map = QyMap.map("name", "商户")
				.setv("code","merchantId")
				.setv("data_controle",0); //0-系统默认不允许调整/1-客户自定义显示列
		list.add(map);

		map = QyMap.map("name","主键")
				.setv("code","id")
				.setv("data_controle",0);
		list.add(map);

		map = QyMap.map("name","编号")
				.setv("code","no")
				.setv("data_controle",1);
		list.add(map);

		map =QyMap.map("name", "仓库")
				.setv("code","warehouse")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "供应商")
				.setv("code", "supplier")
				.setv("data_controle",1);
		list.add(map);


		map = QyMap.map("name", "商品信息库")
				.setv("code", "store_name")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "单据类型")
				.setv("code", "type")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "操作人");
		map.setv("code", "founder")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "备注")
				.setv("code", "remark")
				.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "订单日期")
				.setv("code", "purchase_time")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "订单金额")
				.setv("code", "amount")
				.setv("data_controle",1);
		list.add(map);

		orderColumnMap.put(PrintSettingOrderType.STOREOUT.getKey(), list);

		//[单据打印设置 - 总部调拨]
		list = Lists.newArrayList();
		map = QyMap.map("name", "商户")
				.setv("code","merchantId")
				.setv("data_controle",0); //0-系统默认不允许调整/1-客户自定义显示列
		list.add(map);

		map = QyMap.map("name","主键")
				.setv("code","id")
				.setv("data_controle",0);
		list.add(map);

		map = QyMap.map("name","编号")
				.setv("code","no")
				.setv("data_controle",1);
		list.add(map);

		map =QyMap.map("name", "调出仓库")
				.setv("code","warehouse")
				.setv("data_controle",1);
		list.add(map);

		map =QyMap.map("name", "调入仓库")
				.setv("code","warehouse")
				.setv("data_controle",1);
		list.add(map);


		map = QyMap.map("name", "操作人");
		map.setv("code", "founder")
				.setv("data_controle",1);
		list.add(map);
		map = QyMap.map("name", "调拨日期")
				.setv("code", "purchase_time")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "备注")
				.setv("code", "remark")
				.setv("data_controle",1);
		list.add(map);

		map = QyMap.map("name", "订单金额")
				.setv("code", "amount")
				.setv("data_controle",1);
		list.add(map);

		orderColumnMap.put(PrintSettingOrderType.TRANSFERORDER.getKey(), list);


		//表格列设置
		//总部出库设置
		//[单据打印设置 - 总部订单]
		list = Lists.newArrayList();
		map = QyMap.map("name", "编号")
				.setv("code","no");
		list.add(map);
		map = QyMap.map("name", "条码")
				.setv("code","code");
		list.add(map);
		map = QyMap.map("name", "名称")
				.setv("code","name");
		list.add(map);
		map = QyMap.map("name", "规格型号")
				.setv("code","spec");
		list.add(map);
		map = QyMap.map("name", "采购规格")
				.setv("code","purchase_spec");
		list.add(map);
		map = QyMap.map("name", "采购单位")
				.setv("code","purchase_unit");
		list.add(map);
		map = QyMap.map("name", "采购数量")
				.setv("code","count");
		list.add(map);
		map = QyMap.map("name", "采购单价")
				.setv("code","price");
		list.add(map);
		map = QyMap.map("name", "采购金额")
				.setv("code","amount");
		list.add(map);
		map = QyMap.map("name", "备注")
				.setv("code","remark");
		list.add(map);
		tableColumnMap.put(PrintSettingOrderType.PURCHASEORDER.getKey(),list);

		//[单据打印设置 - 总部入库]
		list = Lists.newArrayList();
		map = QyMap.map("name", "编号")
				.setv("code","no");
		list.add(map);
		map = QyMap.map("name", "条码")
				.setv("code","code");
		list.add(map);
		map = QyMap.map("name", "名称")
				.setv("code","name");
		list.add(map);
		map = QyMap.map("name", "规格型号")
				.setv("code","spec");
		list.add(map);
		map = QyMap.map("name", "采购规格")
				.setv("code","purchase_spec");
		list.add(map);
		map = QyMap.map("name", "采购单位")
				.setv("code","purchase_unit");
		list.add(map);
		map = QyMap.map("name", "采购数量")
				.setv("code","count");
		list.add(map);
		map = QyMap.map("name", "采购单价")
				.setv("code","price");
		list.add(map);
		map = QyMap.map("name", "采购金额")
				.setv("code","amount");
		list.add(map);
		map = QyMap.map("name", "备注")
				.setv("code","remark");
		list.add(map);
		tableColumnMap.put(PrintSettingOrderType.STOREIN.getKey(),list);

		//[单据打印设置 - 总部出库]
		list = Lists.newArrayList();
		map = QyMap.map("name", "编号")
				.setv("code","no");
		list.add(map);
		map = QyMap.map("name", "条码")
				.setv("code","code");
		list.add(map);
		map = QyMap.map("name", "名称")
				.setv("code","name");
		list.add(map);
		map = QyMap.map("name", "规格型号")
				.setv("code","spec");
		list.add(map);
		map = QyMap.map("name", "库存单位")
				.setv("code","unit");
		list.add(map);
		map = QyMap.map("name", "出库数量")
				.setv("code","count");
		list.add(map);
		map = QyMap.map("name", "出库单价")
				.setv("code","price");
		list.add(map);
		map = QyMap.map("name", "出库金额")
				.setv("code","amount");
		list.add(map);
		map = QyMap.map("name", "备注")
				.setv("code","remark");
		list.add(map);
		tableColumnMap.put(PrintSettingOrderType.STOREOUT.getKey(),list);

		//[单据打印设置 - 总部调拨]
		list = Lists.newArrayList();
		map = QyMap.map("name", "编号")
				.setv("code","no");
		list.add(map);
		map = QyMap.map("name", "条码")
				.setv("code","code");
		list.add(map);
		map = QyMap.map("name", "名称")
				.setv("code","name");
		list.add(map);
		map = QyMap.map("name", "规格型号")
				.setv("code","spec");
		list.add(map);
		map = QyMap.map("name", "库存单位")
				.setv("code","unit");
		list.add(map);
		map = QyMap.map("name", "调拨数量")
				.setv("code","count");
		list.add(map);
		map = QyMap.map("name", "备注")
				.setv("code","remark");
		list.add(map);
		tableColumnMap.put(PrintSettingOrderType.TRANSFERORDER.getKey(),list);



		String orderTitle = "";                         //单据标题
		String orderInfo = "";                          //单据底部注意事项
		PrintSettingOrderType printTypeEnum = null;     //单据枚举标识
		Integer printTypeIndex = -1;                    //单据枚举标识(索引方式)
		Searchable searchable = null;                   //条件
		String tableColumn = "";                        //当前单据, 临时提取列名集中存放
		double weight =0;
		String sql = "";
		Long orderId;
		for(int i=0;i<orderTitles.length;i++){
			orderTitle = orderTitles[i];
			printTypeEnum = printSettingOrderTypes[i];
//			printTypeIndex = printTypeEnum.getIndex();

			log.info("printTypeEnum : {}",printTypeEnum);

			//删除已有数据
//			printSettingOrderRepository.deletePringSettingTableDatas(merchantGroupId,printTypeEnum.getKey());
//			printSettingOrderRepository.deletePringSettingOrderDatas(merchantGroupId,printTypeEnum.getKey());
//			printSettingOrderRepository.deletePringSettingOrderDetails(merchantGroupId,printTypeEnum.getKey());
//			printSettingOrderRepository.deletePringSettingOrders(merchantGroupId,printTypeEnum.getKey());
			sql="delete from print_setting_order_table_datas where merchant_group_id=:merchant_group_id and print_type=:print_type";
			map = QyMap.map("merchant_group_id",merchantGroupId)
					.setv("print_type",printTypeEnum.getKey());
			jdbcTemplate.update(sql,map);

			sql="delete from print_setting_order_datas where merchant_group_id=:merchant_group_id and print_type=:print_type";
			map = QyMap.map("merchant_group_id",merchantGroupId)
					.setv("print_type",printTypeEnum.getKey());
			jdbcTemplate.update(sql,map);

			sql="delete from print_setting_order_details where merchant_group_id=:merchant_group_id and print_type=:print_type";
			map = QyMap.map("merchant_group_id",merchantGroupId)
					.setv("print_type",printTypeEnum.getKey());
			jdbcTemplate.update(sql,map);

			sql="delete from print_setting_orders where merchant_group_id=:merchant_group_id and print_type=:print_type";
			map = QyMap.map("merchant_group_id",merchantGroupId)
					.setv("print_type",printTypeEnum.getKey());
			jdbcTemplate.update(sql,map);




			//追加新数据
			//主表配置
			sql = "INSERT INTO print_setting_orders(create_at, is_deleted, status, name, print_type, merchant_group_id) " +
					"values(now(),0,0,:name, :print_type, :merchant_group_id)";
			map = QyMap.map("name",orderTitle)
					.setv("print_type",printTypeEnum.getKey())
					.setv("merchant_group_id",merchantGroupId);
			orderId = jdbcTemplate.insertForAutoIncrement(sql,map);


			//辅助配置
			orderInfo = "1、请收到物品后及时清点，如有短缺、漏装、损坏，请及时联系我们。\n" +
					"2、货品签收后超过15日不予退货，可联系我们酌情调换。\n" +
					"3、本公司出售物品，如有质量问题请及时进反馈，感谢您的信赖与支持。";
			sql = "INSERT INTO print_setting_order_details(create_at, is_deleted, status, order_explain, print_type, title, print_setting_order_id, merchant_group_id)" +
					" values(now(), 0, 0, :order_explain, :print_type, :title, :print_setting_order_id, :merchant_group_id)";
			map = QyMap.map("order_explain",orderInfo)
					.setv("print_type",printTypeEnum.getKey())
					.setv("title",orderTitle)
					.setv("print_setting_order_id",orderId)
					.setv("merchant_group_id",merchantGroupId);
			jdbcTemplate.update(sql,map);

			list = (List<QyMap>)orderColumnMap.get(printTypeEnum.getKey());
			if(CollectionUtils.isEmpty(list)){
				return false;
			}

			for(int j=0;j<list.size();j++){
				map = list.get(j);
				if(map==null){
					break;
				}
				weight = (map.containsKey("weight")?map.getDouble("weight"):0);
				sql = "insert into print_setting_order_datas (create_at, is_deleted, status, code, data_controle, is_print, name, print_type, print_setting_order_id, merchant_group_id, weight)" +
						" VALUES(now(), 0, 0, :code, :data_controle, :is_print, :name, :print_type, :print_setting_order_id, :merchant_group_id, :weight)";
				map = QyMap.map("code",map.getString("code"))
						.setv("data_controle",map.getInt("data_controle"))
						.setv("is_print",true)
						.setv("name",map.getString("name"))
						.setv("print_type",printTypeEnum.getKey())
						.setv("print_setting_order_id",orderId)
						.setv("merchant_group_id",merchantGroupId)
						.setv("weight",weight);
				jdbcTemplate.update(sql,map);
			}

			//表格数据列显示
			list = (List<QyMap>)tableColumnMap.get(printTypeEnum.getKey());
			if(CollectionUtils.isEmpty(list)){
				return false;
			}
			for(int j=0;j<list.size();j++){
				map = list.get(j);
				if(map==null){
					break;
				}
				weight = (map.containsKey("weight")?map.getDouble("weight"):0);
				sql = "insert into print_setting_order_table_datas (create_at, is_deleted, status, code, data_controle, is_print, name, print_type, print_setting_order_id, merchant_group_id, weight)" +
						" VALUES(now(), 0, 0, :code, :data_controle, :is_print, :name, :print_type, :print_setting_order_id, :merchant_group_id, :weight)";
				map = QyMap.map("code",map.getString("code"))
						.setv("data_controle",1)
						.setv("is_print",true)
						.setv("name",map.getString("name"))
						.setv("print_type",printTypeEnum.getKey())
						.setv("print_setting_order_id",orderId)
						.setv("merchant_group_id",merchantGroupId)
						.setv("weight",weight);
				jdbcTemplate.update(sql,map);
			}
		}

		log.info(" 初始化诗句完成");
		return true;
	}

	/**
	 * 验证是否连续发送
	 * @return
	 */
	private boolean isContinuousSend(String redisKey){

		if(!stringRedisTemplate.hasKey(redisKey)){
			return false; //不是连续发送
		}
		BoundHashOperations<String,String,String> hashOperations= stringRedisTemplate.boundHashOps(redisKey);
		String time=hashOperations.get("time");
		if((System.currentTimeMillis()-Long.valueOf(time))<=60000){ //在1分钟之内连续再次发送则为连续发送
			return true;
		}
		return false;
	}
}